﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using jaysJourney_v01.Common;
using jaysJourney_v01.Utils;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using jaysJourney_v01.Utils.Levels;
using Microsoft.Xna.Framework.Storage;
using System.IO;

namespace jaysJourney_v01.States
{
    class EditorState : State
    {
        /**
         * MEMBER VARIABLES
         * */
        GraphicsDevice graphics;
        SpriteBatch spriteBatch;

        
        Texture2D preview;

        Texture2D drawTool;
        Texture2D eraserTool;
        Texture2D moveTool;
        Texture2D drawTool_ac;
        Texture2D eraserTool_ac;
        Texture2D moveTool_ac;
        Texture2D selection;
        Texture2D blockselect;
        Texture2D erasePreview;
        Texture2D start;
        Texture2D menuButton;
        Texture2D dropdown;

        Vector2 startSelect = new Vector2(0, 0);
        Vector2 endSelect = new Vector2(0, 0);
        Texture2D blockselection;
        bool selecting;
        bool movingSelection;
        Vector2 startMoveSelection;
        Vector2 endMoveSelection;
        Vector2 oldEndMoveSelection;
        int[,] selectedBlocks;
        //bool overwrite = true;
        bool altPressed = false;
        Vector2 SelectionOrigin;
        Texture2D Interface_a;
        Texture2D Interface_a2;
        Texture2D Interface_b;
        Texture2D[,] Buttons;
        Texture2D ButtonBack;
        int buttonset = 1;
        Texture2D[] farBG = new Texture2D[NR_SETTINGS];
        Texture2D[] nearBG = new Texture2D[NR_SETTINGS];
        bool menuActive;
        bool submissionActive;
        Texture2D submission;
        Texture2D menu;
        Texture2D menuSelected;
        Texture2D dropdownMapsize;
        Texture2D dropdownSetting;
        Texture2D dropdownSelected;
        Texture2D cashtab;
        bool dropdownMapsizeActive;
        bool dropdownSettingActive;

        InputField draftNameField;
        InputField submissionNameField;
        public bool testSuccessful;
        bool blocksWerePlaced;
        Texture2D fadeout;
        int availableUndos = 0;
        float errorTimer = 0;
        Draft[] Drafts;
        int selectedDraft = 0;
        Texture2D SaveDraftMenu;
        bool savingdraft = false;
        int draftPage = 0;
        Texture2D SubmissionOverview;
        bool overviewOpen;
        private bool loading;
        private bool loading2;
        private Texture2D loadingscreen;
        private Texture2D blockbuttons;
        bool scrolling;
        InputGroup MenuButtons;
        InputGroup SubmitButton;
        InputGroup LoadDraftButtons;
        InputGroup SaveDraftButtons;

        Texture2D[,] blocksprites = new Texture2D[NR_SETTINGS,NUM_BLOCK_TYPES];
        int editMode = 1;
        KeyboardState lastButtonState;
        MouseState lastMouseState;
        bool mousePressed;
        bool justEntered;

        int currentBlockType = 10;
        int offsetX = 0;
        int offsetY = 0;

        double scrollspeedX = 0;
        double scrollspeedY = 0;

        private int LEVEL_WIDTH = SIZE01;
        private int LEVEL_HEIGHT = SIZE01;
        private static int BLOCK_SIZE = 32;
        private static int NUM_BLOCK_TYPES = 99;
        private int BG_WIDTH;
        private int BG_HEIGHT;
        private static int UNDO_AMOUNT = 10;

        private int WINDOW_WIDTH;
        private int WINDOW_HEIGHT;
        private Vector2 menuPosition;
        private Vector2 dropdownMapsizePos;
        private Vector2 dropdownSettingPos;
        private int SETTING = 1;

        int[,] blocks;
        int[, ,] undo;
        private Texture2D submissionSelected;
        private Texture2D submitSelected;
        private int besttime;
        private bool draftListOpen;
        private static String[] SETTINGS = { "Lab", "Wilderness", "Fire", "Ice", "Bongola" };
        private static String SIZE01_NAME = "Tiny";
        private static String SIZE02_NAME = "Small";
        private static String SIZE03_NAME = "Medium";
        private static String SIZE04_NAME = "Big";
        private static String SIZE05_NAME = "Huge";
        private static int[] SIZES = { 60, 90, 120, 150, 200 };
        private static int[] SIZE_COSTS = { 100, 240, 690, 1780, 4420};
        private const int SIZE01 = 60;
        private const int SIZE02 = 90;
        private const int SIZE03 = 120;
        private const int SIZE04 = 150;
        private const int SIZE05 = 200;
        private const int MAX_DRAFT_ENTRIES = 15;
        private const int COST_NORMAL = 2;
        private const int COST_DISSOLVING = 5;
        private static int[] BUTTONSET_LENGTH = { 2, 2, 4 };
        private const int COST_SPIKE = 4;
        private const int NR_SETTINGS = 2;
        private const int COST_INVISIBLE = 6;

        /**
         * METHODS
         * */

        public EditorState(String name, StateManager stateManager) : base(name, stateManager) { }

        public override void initialize()
        {
            if (!Directory.Exists("Drafts"))
            {
                Directory.CreateDirectory("Drafts");
            }
            LoadContent();

            initializeLevel();


            initiateButtons();
        }

        public override void onEnterState()
        {
            mousePressed = false;
            this.WINDOW_HEIGHT = graphics.Viewport.Height;
            this.WINDOW_WIDTH = graphics.Viewport.Width;
            menuPosition = new Vector2(WINDOW_WIDTH / 2 - menu.Width / 2, WINDOW_HEIGHT / 2 - menu.Height / 2);
            dropdownMapsizePos = new Vector2(menuPosition.X + 225, menuPosition.Y + 255);
            dropdownSettingPos = new Vector2(menuPosition.X + 225, menuPosition.Y + 335);
            relocateButtons();
            justEntered = true;
            getGame().IsMouseVisible = false;
        }

        private void relocateButtons()
        {

            List<Button> buttons = MenuButtons.getButtonList();
            int pos = 10;
            foreach (Button button in buttons)
            {
                button.setNewPosition((int)this.menuPosition.X + 10, (int)this.menuPosition.Y + pos);
                pos += 79;
                if (button.getName() == "SUBMIT LEVEL") button.setNewPosition((int)this.menuPosition.X + 215, (int)this.menuPosition.Y + 168);
                if (button.getName() == "TEST LEVEL") button.setNewPosition((int)this.menuPosition.X + 215, (int)this.menuPosition.Y + 10);

            }
            foreach (Button button in SubmitButton.getButtonList())
            {
                button.setNewPosition((int)this.menuPosition.X + 275, (int)this.menuPosition.Y + 300);
            }
            submissionNameField.setNewPosition((int)menuPosition.X + 230, (int)menuPosition.Y + 89);

            int i = 0;
            foreach (Button button in SaveDraftButtons.getButtonList())
            {
                if (i == 0) button.setNewPosition((int)menuPosition.X + 15, (int)menuPosition.Y + 345);
                else button.setNewPosition((int)this.menuPosition.X + 295, (int)this.menuPosition.Y + 325);
                i++;
            }
            i = 0;
            foreach (Button button in LoadDraftButtons.getButtonList())
            {
                button.setNewPosition((int)menuPosition.X + 70 + 80 * i, (int)menuPosition.Y + 330);
                if (i == 2) button.setNewPosition((int)this.menuPosition.X + 295, (int)this.menuPosition.Y + 330);
                i++;
            }
        }

        private void resetSetting()
        {
            this.SETTING = 1;
            this.LEVEL_HEIGHT = SIZE01;
            this.LEVEL_WIDTH = SIZE01;
        }

        private void initiateButtons()
        {
            MenuButtons = new InputGroup(this, this.spriteBatch);
            MenuButtons.addButton(new Button(this, "LOAD DRAFT", @"Textures\Interface\editor_button", @"Textures\Interface\editor_button_ac", (int)this.menuPosition.X + 10, (int)this.menuPosition.Y + 10, Color.White, true, true));
            MenuButtons.addButton(new Button(this, "SAVE DRAFT", @"Textures\Interface\editor_button", @"Textures\Interface\editor_button_ac", (int)this.menuPosition.X + 10, (int)this.menuPosition.Y + 89, Color.White, false, true));
            MenuButtons.addButton(new Button(this, "CLEAR ALL", @"Textures\Interface\editor_button", @"Textures\Interface\editor_button_ac", (int)this.menuPosition.X + 10, (int)this.menuPosition.Y + 168, Color.White, false, true));
            MenuButtons.addButton(new Button(this, "MAIN MENU", @"Textures\Interface\editor_button", @"Textures\Interface\editor_button_ac", (int)this.menuPosition.X + 10, (int)this.menuPosition.Y + 247, Color.White, false, true));
            MenuButtons.addButton(new Button(this, "EXIT GAME", @"Textures\Interface\editor_button", @"Textures\Interface\editor_button_ac", (int)this.menuPosition.X + 10, (int)this.menuPosition.Y + 326, Color.White, false, true));
            MenuButtons.addButton(new Button(this, "TEST LEVEL", @"Textures\Interface\button_standard_v2", @"Textures\Interface\button_standard_v2_ac", (int)this.menuPosition.X + 215, (int)this.menuPosition.Y + 10, Color.White, false, true));
            submissionNameField = new InputField(this, "Enter Name", new Vector2(menuPosition.X + 215, menuPosition.Y + 100), @"Textures\Textfield\stxtField", @"Textures\Textfield\stxtFieldHover", @"Textures\Textfield\stxtFieldAc", 20, false, false, false);
            MenuButtons.addButton(submissionNameField);
            MenuButtons.addButton(new Button(this, "SUBMIT LEVEL", @"Textures\Interface\button_standard_v2", @"Textures\Interface\button_standard_v2_ac", (int)this.menuPosition.X + 215, (int)this.menuPosition.Y + 168, Color.White, false, true));

            SubmitButton = new InputGroup(this, this.spriteBatch);
            SubmitButton.addButton(new Button(this, "SUBMIT LEVEL", @"Textures\Interface\editor_button", @"Textures\Interface\editor_button_ac", (int)this.menuPosition.X + 215, (int)this.menuPosition.Y + 168, Color.White, false, true));

            LoadDraftButtons = new InputGroup(this, spriteBatch);
            LoadDraftButtons.addButton(new Button(this, "LEFT", @"Textures\Interface\back_btn", @"Textures\Interface\back_btn_ac", (int)this.menuPosition.X + 70, (int)this.menuPosition.Y + 330, Color.White, false, false));
            LoadDraftButtons.addButton(new Button(this, "RIGHT", @"Textures\Interface\arrow_btn", @"Textures\Interface\arrow_btn_ac", (int)this.menuPosition.X + 150, (int)this.menuPosition.Y + 335, Color.White, false, false));
            LoadDraftButtons.addButton(new Button(this, "LOAD", @"Textures\Interface\editor_button", @"Textures\Interface\editor_button_ac", (int)this.menuPosition.X + 295, (int)this.menuPosition.Y + 330, Color.White, true, true));


            SaveDraftButtons = new InputGroup(this, spriteBatch);
            draftNameField = new InputField(this, "Enter Name", new Vector2(menuPosition.X + 15, menuPosition.Y + 345), @"Textures\Textfield\stxtField", @"Textures\Textfield\stxtFieldHover", @"Textures\Textfield\stxtFieldAc", 20, true, false, false);
            SaveDraftButtons.addButton(draftNameField);
            SaveDraftButtons.addButton(new Button(this, "SAVE", @"Textures\Interface\editor_button", @"Textures\Interface\editor_button_ac", (int)this.menuPosition.X + 295, (int)this.menuPosition.Y + 325, Color.White, true, true));

        }

        private void initializeLevel()
        {

            blocks = new int[LEVEL_WIDTH, LEVEL_HEIGHT];
            undo = new int[UNDO_AMOUNT, LEVEL_WIDTH, LEVEL_HEIGHT];
            this.WINDOW_HEIGHT = graphics.Viewport.Height;
            this.WINDOW_WIDTH = graphics.Viewport.Width;
            menuPosition = new Vector2(WINDOW_WIDTH / 2 - menu.Width / 2, WINDOW_HEIGHT / 2 - menu.Height / 2);
            for (int i = 0; i < LEVEL_WIDTH; i++)
            {
                for (int j = 0; j < LEVEL_HEIGHT; j++)
                {
                    blocks[i, j] = 0;
                }
            }
            this.testSuccessful = false;
            clearUndo();
            offsetX = 0;
            offsetY = LEVEL_HEIGHT * BLOCK_SIZE - WINDOW_HEIGHT;
        }
        private void clearUndo()
        {
            availableUndos = 0;
            undo = new int[UNDO_AMOUNT, LEVEL_WIDTH, LEVEL_HEIGHT];
            for (int i = 0; i < LEVEL_WIDTH; i++)
            {
                for (int j = 0; j < LEVEL_HEIGHT; j++)
                {
                    for (int k = 0; k < UNDO_AMOUNT; k++)
                    {
                        undo[k, i, j] = 0;
                    }
                }
            }
        }
        private void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.

            graphics = this.getGame().GraphicsDevice;
            spriteBatch = this.parentSpriteBatch;
            ContentManager Content = this.getGame().Content;
            drawTool = Content.Load<Texture2D>(@"Textures\Editor\draw_tool");
            eraserTool = Content.Load<Texture2D>(@"Textures\Editor\eraser_tool");
            selection = Content.Load<Texture2D>(@"Textures\Editor\selected");
            blockselect = Content.Load<Texture2D>(@"Textures\Editor\selected2");
            blockselection = Content.Load<Texture2D>(@"Textures\Editor\blocks");
            for (int i = 0; i < NR_SETTINGS; i++)
            {
                blocksprites[i,1] = Content.Load<Texture2D>(@"Textures\Editor\start");
                blocksprites[i, 2] = Content.Load<Texture2D>(@"Textures\Editor\block_finish");
                blocksprites[i, 9] = Content.Load<Texture2D>(@"Textures\Editor\Setting" + (i + 1) + @"\blockt");
                blocksprites[i, 10] = Content.Load<Texture2D>(@"Textures\Editor\Setting"+(i+1)+@"\block");
                blocksprites[i, 11] = Content.Load<Texture2D>(@"Textures\Editor\Setting" + (i + 1) + @"\block_explosive");
                blocksprites[i, 12] = Content.Load<Texture2D>(@"Textures\Editor\Setting" + (i + 1) + @"\spikeblock_1");
                blocksprites[i, 13] = Content.Load<Texture2D>(@"Textures\Editor\Setting" + (i + 1) + @"\block_invis");
            }
            
            preview = Content.Load<Texture2D>(@"Textures\Editor\preview");
            moveTool_ac = Content.Load<Texture2D>(@"Textures\Editor\move_tool_ac");
            drawTool_ac = Content.Load<Texture2D>(@"Textures\Editor\draw_tool_ac");
            eraserTool_ac = Content.Load<Texture2D>(@"Textures\Editor\eraser_tool_ac");
            moveTool = Content.Load<Texture2D>(@"Textures\Editor\move_tool");
            erasePreview = Content.Load<Texture2D>(@"Textures\Editor\erase_preview");
            start = Content.Load<Texture2D>(@"Textures\Editor\start");
            Interface_a = Content.Load<Texture2D>(@"Textures\Editor\interface_a");
            Interface_a2 = Content.Load<Texture2D>(@"Textures\Editor\interface_a2");
            Interface_b = Content.Load<Texture2D>(@"Textures\Editor\tools tab");
            Buttons = new Texture2D[2, 5];
            Buttons[0, 0] = Content.Load<Texture2D>(@"Textures\Editor\common_buttons");
            Buttons[0, 1] = Content.Load<Texture2D>(@"Textures\Editor\button_start");
            Buttons[0, 2] = Content.Load<Texture2D>(@"Textures\Editor\button_finish");
            Buttons[1, 0] = Content.Load<Texture2D>(@"Textures\Editor\building_buttons");
            Buttons[1, 1] = Content.Load<Texture2D>(@"Textures\Editor\button_standard");
            Buttons[1, 2] = Content.Load<Texture2D>(@"Textures\Editor\button_explosive");
            Buttons[1, 3] = Content.Load<Texture2D>(@"Textures\Editor\button_spike");
            Buttons[1, 4] = Content.Load<Texture2D>(@"Textures\Editor\button_invis");
            ButtonBack = Content.Load<Texture2D>(@"Textures\Editor\button_back");
            //Butto
            for(int i = 0; i < NR_SETTINGS; i++){
                farBG[i] = Content.Load<Texture2D>(@"Textures\Settings\Setting"+(i+1)+@"\background");
                nearBG[i] = Content.Load<Texture2D>(@"Textures\Settings\Setting"+(i+1)+@"\parallax_bg");
            }
            
            menuButton = Content.Load<Texture2D>(@"Textures\Editor\button_menu");
            menu = Content.Load<Texture2D>(@"Textures\Editor\menu2");
            menuSelected = Content.Load<Texture2D>(@"Textures\Editor\menu_selected");
            dropdownMapsize = Content.Load<Texture2D>(@"Textures\Editor\dropdown_mapsize");
            dropdownSetting = Content.Load<Texture2D>(@"Textures\Editor\dropdown_setting");
            dropdownSelected = Content.Load<Texture2D>(@"Textures\Editor\dropdown_selected");
            submission = Content.Load<Texture2D>(@"Textures\Editor\menu_submission");
            submissionSelected = Content.Load<Texture2D>(@"Textures\Editor\submission_selected");
            submitSelected = Content.Load<Texture2D>(@"Textures\Editor\Submit_Selected");
            fadeout = Content.Load<Texture2D>(@"Textures\Editor\fadeout");
            SaveDraftMenu = Content.Load<Texture2D>(@"Textures\Editor\savedraft");
            SubmissionOverview = Content.Load<Texture2D>(@"Textures\Editor\submissionOverview");
            this.loadingscreen = this.getGame().Content.Load<Texture2D>(@"Textures\Preloader\loadingscreen");
            dropdown = Content.Load<Texture2D>(@"Textures\Editor\dropdown");
            blockbuttons = Content.Load<Texture2D>(@"Textures\Editor\block-buttons");
            cashtab = Content.Load<Texture2D>(@"Textures\Editor\cashtab");

            BG_WIDTH = nearBG[SETTING-1].Width;
            BG_HEIGHT = nearBG[SETTING-1].Height;


            // TODO: use this.Content to load your game content here
        }
        public override void update(GameTime gameTime)
        {
            if (loading)
            {
                loading = false;
                submitLevelAction();
            }
            if (loading2)
            {
                loading2 = false;
                testLevelAction();
            }


            if (!menuActive) inputUpdate(gameTime);
            else
            {
                menuInputUpdate(gameTime);
                if (savingdraft) SaveDraftButtons.update(gameTime);

            }
            if (errorTimer > 0) errorTimer -= (float)(gameTime.ElapsedGameTime.Milliseconds) / 1000;
        }
        private void menuButtonUpdate(GameTime tpf)
        {
            Button clicked = MenuButtons.update(tpf);
            if (clicked != null)
            {
                switch (clicked.getName())
                {
                    case "SAVE DRAFT":
                        menuButtonAction(0);
                        break;
                    case "LOAD DRAFT":
                        menuButtonAction(1);
                        break;
                    case "CLEAR ALL":
                        menuButtonAction(2);
                        break;
                    case "MAIN MENU":
                        menuButtonAction(3);
                        break;
                    case "EXIT GAME":
                        menuButtonAction(4);
                        break;
                    case "SUBMIT LEVEL":
                        // if (checkSubmissionReady()) 
                        overviewOpen = true;
                        break;
                    case "TEST LEVEL":
                        testLevel();
                        break;
                }
            }
        }
        private void menuInputUpdate(GameTime tpf)
        {
            if(mousePressed)mousePressed = false;
            KeyboardState newState = Keyboard.GetState();
            MouseState mstate = Mouse.GetState();
            
            if (overviewOpen)
            {
                Button clicked = SubmitButton.update(tpf);
                if (clicked != null)
                {
                    submitLevel();
                    overviewOpen = false;
                }
            }
            if (savingdraft)
            {
                Button clicked = this.SaveDraftButtons.update(tpf);
                if (clicked != null && clicked.getName() == "SAVE")
                {
                    if (SaveDraftButtons.getContent("Enter Name").Length > 0) saveDraft(SaveDraftButtons.getContent("Enter Name"));
                    savingdraft = false;
                }

            }
            if (draftListOpen)
            {

                Button clicked = this.LoadDraftButtons.update(tpf);
                if (clicked != null)
                {
                    switch (clicked.getName())
                    {
                        case "LEFT":
                            if (draftPage > 0)
                            {
                                draftPage--;
                                selectedDraft = draftPage * MAX_DRAFT_ENTRIES;
                            }
                            break;
                        case "RIGHT":
                            if (draftPage < (Drafts.Length - 1) / MAX_DRAFT_ENTRIES)
                            {
                                draftPage++;
                                selectedDraft = draftPage * MAX_DRAFT_ENTRIES;
                            }
                            break;
                        case "LOAD":
                            openDraft(selectedDraft);
                            draftListOpen = false;
                            menuActive = false;
                            break;
                    }
                }
            }
            if (mstate.LeftButton == ButtonState.Pressed && lastMouseState.LeftButton == ButtonState.Released)
            {
                if (!draftListOpen && !savingdraft && !overviewOpen)menuClick(mstate);
                else if (draftListOpen) draftlistClick(mstate);
            }
            if (newState.IsKeyDown(Keys.Escape) && lastButtonState.IsKeyUp(Keys.Escape))
            {
                escapeAction();
            }
            if (!draftListOpen && !savingdraft && !overviewOpen) menuButtonUpdate(tpf);
            else
            {
                dropdownMapsizeActive = false;
                dropdownSettingActive = false;
            }
            this.lastButtonState = newState;
            this.lastMouseState = mstate;
        }
        private void draftlistClick(MouseState ms)
        {
            Console.WriteLine(Drafts.Length / 15);
            for (int i = 0; i < 15; i++)
            {
                if (ms.X > menuPosition.X + 30 && ms.X < menuPosition.X + 580 && ms.Y > menuPosition.Y + 33 + 20 * i && ms.Y < menuPosition.Y + 53 + 20 * i)
                {
                    if (i + draftPage * MAX_DRAFT_ENTRIES < Drafts.Length) selectedDraft = i + draftPage * MAX_DRAFT_ENTRIES;
                }
            }
        }
        private void testLevel()
        {
            if (!checkForStartAndGoal()) return;
            loading2 = true;
        }
        private void testLevelAction()
        {
            if (!checkForStartAndGoal()) return;
            PlayState playState = ((PlayState)this.getStateManager().getState("playState"));

            // load world
            String world = encodeCurrentLevel();

            // update currentWorld
            playState.getLevel().curWorldData = world;
            playState.getLevel().splitStringtoWorld();
            playState.getLevel().initTexturesAnimations();

            playState.setLvlData(new Level("", SETTINGS[SETTING], "", getGame().activePlayer.getUsername(), 0, 0, 0d, "", 0, "", 0));

            // prepare world
            playState.jay.newPosition = ((PlayState)this.getStateManager().getState("playState")).getLevel().StartPoint * CONST.BLOCKSIZE;
            playState.resetLevel();

            // start world
            this.getStateManager().setActiveState("playState");
        }
        private void saveUndo()
        {
            if (availableUndos < 10) availableUndos++;
            for (int i = UNDO_AMOUNT - 1; i > 0; i--)
            {
                for (int j = 0; j < LEVEL_WIDTH; j++)
                {
                    for (int k = 0; k < LEVEL_HEIGHT; k++)
                    {
                        undo[i, j, k] = undo[i - 1, j, k];
                    }
                }
            }
            for (int j = 0; j < LEVEL_WIDTH; j++)
            {
                for (int k = 0; k < LEVEL_HEIGHT; k++)
                {
                    undo[0, j, k] = blocks[j, k];
                }
            }
        }
        private void undoAction()
        {
            if (availableUndos == 0) return;
            availableUndos--;
            for (int j = 0; j < LEVEL_WIDTH; j++)
            {
                for (int k = 0; k < LEVEL_HEIGHT; k++)
                {
                    blocks[j, k] = undo[0, j, k];
                }
            }
            for (int i = 0; i < UNDO_AMOUNT - 1; i++)
            {
                for (int j = 0; j < LEVEL_WIDTH; j++)
                {
                    for (int k = 0; k < LEVEL_HEIGHT; k++)
                    {
                        undo[i, j, k] = undo[i + 1, j, k];
                    }
                }
            }

        }
        private void menuClick(MouseState ms)
        {
            for (int i = 0; i < 5; i++)
            {
                
                if (dropdownSettingActive && ms.X > dropdownSettingPos.X && ms.X < dropdownSettingPos.X + dropdown.Width && ms.Y > dropdownSettingPos.Y +50 +50 * i && ms.Y < dropdownSettingPos.Y + 100 + 50 * i)
                {
                    if (i < NR_SETTINGS)
                    {

                        if (getGame().activePlayer.getCurrentLevel() >= i * 5)
                        {
                            SETTING = i + 1;
                            BG_WIDTH = nearBG[SETTING - 1].Width;
                            BG_HEIGHT = nearBG[SETTING - 1].Height;
                        }
                    }
                }
                if (dropdownMapsizeActive && ms.X > dropdownMapsizePos.X && ms.X < dropdownMapsizePos.X + dropdown.Width && ms.Y > dropdownMapsizePos.Y + 50 + 50 * i && ms.Y < dropdownMapsizePos.Y + 100 + 50 * i)
                {
                    dropdownMapsizeAction(i);
                }
            }
            
            if (!dropdownMapsizeActive &&ms.X > dropdownSettingPos.X && ms.X < dropdownSettingPos.X + dropdown.Width && ms.Y > dropdownSettingPos.Y && ms.Y < dropdownSettingPos.Y + 50)
            {
                dropdownSettingActive = !dropdownSettingActive;
            }
            else dropdownSettingActive = false;
            if (ms.X > dropdownMapsizePos.X && ms.X < dropdownMapsizePos.X + dropdown.Width && ms.Y > dropdownMapsizePos.Y && ms.Y < dropdownMapsizePos.Y + 50)
            {
                dropdownMapsizeActive = !dropdownMapsizeActive;

            }
            else dropdownMapsizeActive = false;
        }
        private void saveDraft(String name)
        {
            if (!Directory.Exists("Drafts"))
            {
                Directory.CreateDirectory("Drafts");
            }
            Console.Write(DateTime.Now.ToString());
            using (StreamWriter outfile =
            new StreamWriter(@"Drafts\" + name + ".jjd"))
            {
                outfile.Write(encodeCurrentDraft(name));
            }
        }

        private void loadDraft()
        {
            if (!Directory.Exists("Drafts"))
            {
                Directory.CreateDirectory("Drafts");
            }
            createDraftList();
            draftListOpen = true;
        }
        private void openDraft(int nr)
        {
            if (Drafts.Length == 0) return;
            LEVEL_WIDTH = Drafts[nr].width;
            LEVEL_HEIGHT = Drafts[nr].height;
            SETTING = Drafts[nr].Setting;
            initializeLevel();
            blocks = Drafts[nr].blocks;
        }
        private Draft saveStringAsDraft(String data)
        {
            Draft draft = new Draft();
            int userlength;
            Int32.TryParse(data.Substring(0, 2), out userlength);
            draft.creator = data.Substring(2, userlength);
            int namelength;
            Int32.TryParse(data.Substring(2 + userlength, 2), out namelength);
            draft.name = data.Substring(4 + userlength, namelength);
            int offset = 4 + namelength + userlength;
            Int32.TryParse(data.Substring(offset, 3), out draft.width);
            Int32.TryParse(data.Substring(offset + 3, 3), out draft.height);
            Int32.TryParse(data.Substring(offset + 6, 2), out draft.Setting);
            offset += 8;
            draft.blocks = new int[draft.width, draft.height];
            for (int i = 0; i < draft.width; i++)
            {
                for (int j = 0; j < draft.height; j++)
                {
                    Int32.TryParse(data.Substring(offset + (j * 2) + (i * 2 * draft.height), 2), out draft.blocks[i, j]);
                }
            }
            return draft;
        }
        private void createDraftList()
        {
            try
            {
                var files = from file in Directory.EnumerateFiles(@"Drafts\",
                                "*.jjd", SearchOption.AllDirectories)
                            from line in File.ReadLines(file)
                            //where line.Contains("Microsoft")
                            select new
                            {
                                File = file,
                                Line = line
                            };
                Drafts = new Draft[files.Count()];
                int i = 0;
                foreach (var f in files)
                {
                    Drafts[i] = saveStringAsDraft(f.Line);
                    i++;
                }
            }
            catch (UnauthorizedAccessException UAEx)
            {
                Console.WriteLine(UAEx.Message);
            }
            catch (PathTooLongException PathEx)
            {
                Console.WriteLine(PathEx.Message);
            }
        }
        private void dropdownMapsizeAction(int s)
        {
            int size = 50;
            switch (s)
            {
                case 0:
                    size = 60;
                    break;
                case 1:
                    size = 90;
                    break;
                case 2:
                    size = 120;
                    break;
                case 3:
                    size = 150;
                    break;
                case 4:
                    size = 200;
                    break;
            }
            if (size <= LEVEL_WIDTH && !checkForShrinkable(size))
            {
                triggerErrorMessage("You can't shrink the level anymore since this would destroy blocks.");
                return;
            }
            int[,] newblocks = new int[size, size];
            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    newblocks[i, j] = 0;
                }
            }
            if (size < LEVEL_WIDTH)
            {
                for (int i = 0; i < Math.Min(LEVEL_WIDTH, size); i++)
                {
                    for (int j = 0; j < Math.Min(LEVEL_HEIGHT, size); j++)
                    {
                        newblocks[i, j + size - Math.Min(LEVEL_HEIGHT, size)] = blocks[i, j+LEVEL_HEIGHT-size];
                    }
                }
            }
            else
                for (int i = 0; i < Math.Min(LEVEL_WIDTH, size); i++)
                {
                    for (int j = 0; j < Math.Min(LEVEL_HEIGHT, size); j++)
                    {
                        newblocks[i, j + size - Math.Min(LEVEL_HEIGHT, size)] = blocks[i, j];
                    }
                }
            offsetY += (size - LEVEL_HEIGHT) * BLOCK_SIZE;
            LEVEL_WIDTH = size;
            LEVEL_HEIGHT = size;
            blocks = newblocks;
            clearUndo();
        }
        private bool checkForShrinkable(int newsize)
        {
            for (int i = 0; i < LEVEL_WIDTH; i++)
            {
                for (int j = 0; j < LEVEL_HEIGHT; j++)
                {
                    if ((j < LEVEL_HEIGHT - newsize) || (i >= newsize))
                    {
                        if (blocks[i, j] != 0) return false;
                    }
                }
            }
            return true;
        }
        private void menuButtonAction(int nr)
        {
            switch (nr)
            {
                case 0:
                    savingdraft = true;
                    break;
                case 1:
                    loadDraft();
                    break;
                case 2:
                    resetSetting();
                    initializeLevel();
                    break;
                case 3:
                    getStateManager().setActiveState("menuState");
                    break;
                case 4:
                    getGame().Exit();
                    break;

            }
        }
        private void inputUpdate(GameTime tpf)
        {
            KeyboardState newState = Keyboard.GetState();
            MouseState mstate = Mouse.GetState();

            if (newState.IsKeyDown(Keys.LeftControl) && newState.IsKeyDown(Keys.Z) && lastButtonState.IsKeyUp(Keys.Z))
            {
                undoAction();
            }
            if (newState.IsKeyDown(Keys.LeftAlt) && !altPressed)
            {
                if (movingSelection) rewriteOldBlocks();
                altPressed = true;
            }
            if (newState.IsKeyUp(Keys.LeftAlt) && altPressed)
            {
                if (movingSelection) eraseOldBlocks();
                altPressed = false;
            }
            //if (mstate.RightButton == ButtonState.Pressed && lastMouseState.RightButton == ButtonState.Released && buttonset != 0) buttonset = 0;
            if (mstate.LeftButton == ButtonState.Pressed && lastMouseState.LeftButton == ButtonState.Released)
            {
                leftClick();
            }
            if (mstate.LeftButton == ButtonState.Released && lastMouseState.LeftButton == ButtonState.Pressed)
            {
                leftReleased();
            }
            if (mstate.ScrollWheelValue != lastMouseState.ScrollWheelValue)
            {
                cycleBlocks(lastMouseState.ScrollWheelValue - mstate.ScrollWheelValue);
            }
            if (mstate.LeftButton == ButtonState.Pressed && lastMouseState.LeftButton == ButtonState.Pressed)
            {
                leftPressed();
            }
            if (newState.IsKeyDown(Keys.Escape) && lastButtonState.IsKeyUp(Keys.Escape))
            {
                escapeAction();
            }
            if (newState.IsKeyDown(Keys.D0) && lastButtonState.IsKeyUp(Keys.D0)) numKeyPressed(Keys.D0);
            if (newState.IsKeyDown(Keys.D1) && lastButtonState.IsKeyUp(Keys.D1)) numKeyPressed(Keys.D1);
            if (newState.IsKeyDown(Keys.D2) && lastButtonState.IsKeyUp(Keys.D2)) numKeyPressed(Keys.D2);
            if (newState.IsKeyDown(Keys.D3) && lastButtonState.IsKeyUp(Keys.D3)) numKeyPressed(Keys.D3);
            if (newState.IsKeyDown(Keys.D4) && lastButtonState.IsKeyUp(Keys.D4)) numKeyPressed(Keys.D4);
            scrolling = false;
            if (newState.IsKeyDown(Keys.Right)) arrowKeyPressed(Keys.Right);
            if (newState.IsKeyDown(Keys.Left)) arrowKeyPressed(Keys.Left);
            if (newState.IsKeyDown(Keys.Down)) arrowKeyPressed(Keys.Down);
            if (newState.IsKeyDown(Keys.Up)) arrowKeyPressed(Keys.Up);
            this.lastButtonState = newState;
            this.lastMouseState = mstate;
            scroll(tpf);
        }
        private void arrowKeyPressed(Keys key)
        {
            scrolling = true;
            if (key == Keys.Right && offsetX < LEVEL_WIDTH * BLOCK_SIZE - WINDOW_WIDTH / 2) scrollspeedX = 1;
            else if (key == Keys.Left && offsetX > -WINDOW_WIDTH / 2) scrollspeedX = -1;
            if (key == Keys.Down && offsetY < LEVEL_HEIGHT * BLOCK_SIZE - WINDOW_HEIGHT / 2) scrollspeedY = 1;
            else if (key == Keys.Up && offsetY > -WINDOW_HEIGHT / 2) scrollspeedY = -1;
            if (offsetX < -WINDOW_WIDTH / 2) { scrollspeedX = 0; offsetX = -WINDOW_WIDTH / 2; }
            if (offsetX > LEVEL_WIDTH * BLOCK_SIZE - WINDOW_WIDTH / 2) { scrollspeedX = 0; offsetX = LEVEL_WIDTH * BLOCK_SIZE - WINDOW_WIDTH / 2; }
            if (offsetY < -WINDOW_HEIGHT / 2) { scrollspeedY = 0; offsetY = -WINDOW_HEIGHT / 2; }
            if (offsetY > LEVEL_HEIGHT * BLOCK_SIZE - WINDOW_HEIGHT / 2) { scrollspeedY = 0; offsetY = LEVEL_HEIGHT * BLOCK_SIZE - WINDOW_HEIGHT / 2; }
        }
        private void numKeyPressed(Keys key)
        {
            switch (key)
            {
                case Keys.D0:
                    if (buttonset > 0) buttonset = 0;
                    break;
                case Keys.D1:
                    keyButtonSwitch(1);
                    break;
                case Keys.D2:
                    keyButtonSwitch(2);
                    break;
                case Keys.D3:
                    keyButtonSwitch(3);
                    break;
                case Keys.D4:
                    keyButtonSwitch(4);
                    break;
                case Keys.D5:
                    keyButtonSwitch(5);
                    break;

            }
        }
        private void keyButtonSwitch(int key)
        {
            switch (buttonset)
            {
                case 0:
                    if (key <= BUTTONSET_LENGTH[0]) buttonset = key;
                    break;
                case 1:
                    if (key <= BUTTONSET_LENGTH[1]) currentBlockType = key;
                    clearVariables();
                    editMode = 1;
                    break;
                case 2:
                    if (key <= BUTTONSET_LENGTH[2]) setCurrentBlockType(key + 9);
                    clearVariables();
                    editMode = 1;
                    break;
            }
        }
        private void escapeAction()
        {
            if (!menuActive) menuActive = true;
            else if (overviewOpen) overviewOpen = false;
            else if (submissionActive) submissionActive = false;
            else if (savingdraft) savingdraft = false;
            else if (draftListOpen) draftListOpen = false;
            else if (menuActive) menuActive = false;
        }
        private void cycleBlocks(int value)
        {
            switch (buttonset)
            {
                case 1:
                    if (currentBlockType > 9)
                    {
                        currentBlockType = 1;
                        return;
                    }
                    if (value < 0)
                    {
                        if (currentBlockType < BUTTONSET_LENGTH[1]) currentBlockType++;
                        else currentBlockType = 1;
                    }
                    else
                    {
                        if (currentBlockType > 1) currentBlockType--;
                        else currentBlockType = BUTTONSET_LENGTH[1];
                    }
                    break;
                case 2:
                    if (currentBlockType > 19 || currentBlockType < 9)
                    {
                        currentBlockType = 10;
                        return;
                    }
                    if (value < 0)
                    {
                        if (currentBlockType < 9 + BUTTONSET_LENGTH[2]) setCurrentBlockType(currentBlockType + 1);
                        else setCurrentBlockType(10);
                    }
                    else
                    {
                        if (currentBlockType > 10) setCurrentBlockType(currentBlockType - 1);
                        else setCurrentBlockType(BUTTONSET_LENGTH[2] + 9);
                    }
                    break;
            }
        }
        private bool submitLevel()
        {
            if (!checkSubmissionReady()) return false;
            loading = true;
            return true;
        }
        private void submitLevelAction()
        {
            if (!checkSubmissionReady()) return;
            String levelstring;
            if (LEVEL_WIDTH < 100)
            {
                levelstring = "0" + LEVEL_WIDTH + "0" + LEVEL_HEIGHT;
            }
            else levelstring = LEVEL_WIDTH + "" + LEVEL_HEIGHT;

            WebSaver.saveWorld(this.MenuButtons.getContent("Enter Name"), getGame().activePlayer.getUsername(), "0" + SETTING, levelstring, encodeCurrentLevel(), this.besttime.ToString());
            getGame().activePlayer.setMoney(getGame().activePlayer.getMoney() - calculateCost());
            WebSaver.userUpdate(getGame().activePlayer.getUsername(), getGame().activePlayer.getMoney(), getGame().activePlayer.getXp());
            getGame().pushMessage("Level upload successful!", false);
        }
        public void setBesttime(int time)
        {
            if (time < this.besttime || !this.testSuccessful) this.besttime = time;
        }
        private String encodeCurrentLevel()
        {
            String levelstring;
            if (LEVEL_WIDTH < 100)
            {
                levelstring = "0" + LEVEL_WIDTH + "0" + LEVEL_HEIGHT + "0" + SETTING;
            }
            else levelstring = LEVEL_WIDTH + "" + LEVEL_HEIGHT + "0" + SETTING;
            for (int i = 0; i < LEVEL_WIDTH; i++)
            {
                for (int j = 0; j < LEVEL_HEIGHT; j++)
                {
                    if (blocks[i, j] < 10) levelstring += "0";
                    levelstring += blocks[i, j];
                }
            }
            return levelstring;
        }
        private String encodeCurrentDraft(String levelname)
        {
            String levelstring = "";
            String user = "";
            user += getGame().activePlayer.getUsername();
            if (user.Length > 9)
            {
                levelstring += user.Length + "" + user;
            }
            else
            {
                levelstring += 0 + "" + user.Length + "" + user;
            }
            if (levelname.Length > 9)
            {
                levelstring += levelname.Length + "" + levelname;
            }
            else
            {
                levelstring += 0 + "" + levelname.Length + "" + levelname;
            }
            if (LEVEL_WIDTH < 100)
            {
                levelstring += "0" + LEVEL_WIDTH + "0" + LEVEL_HEIGHT + "0" + SETTING;
            }
            else levelstring += LEVEL_WIDTH + "" + LEVEL_HEIGHT + "0" + SETTING;
            /*
            String datestring = DateTime.Now.ToString();
            levelstring += datestring.Length;
            levelstring += datestring;
             * */
            for (int i = 0; i < LEVEL_WIDTH; i++)
            {
                for (int j = 0; j < LEVEL_HEIGHT; j++)
                {
                    if (blocks[i, j] < 10) levelstring += "0";
                    levelstring += blocks[i, j];
                }
            }
            return levelstring;
        }
        private int countAllBlocks()
        {
            int blockcount = 0;
            for (int i = 0; i < LEVEL_WIDTH; i++)
            {
                for (int j = 0; j < LEVEL_HEIGHT; j++)
                {
                    if (blocks[i, j] != 0) blockcount++;
                }
            }
            return blockcount;
        }
        private int countBlocks(int type)
        {
            int blockcount = 0;
            for (int i = 0; i < LEVEL_WIDTH; i++)
            {
                for (int j = 0; j < LEVEL_HEIGHT; j++)
                {
                    if (blocks[i, j] == type) blockcount++;
                }
            }
            return blockcount;
        }
        private int calculateCost()
        {
            int cost = 0;
            cost += countBlocks(10) * COST_NORMAL;
            cost += countBlocks(11) * COST_DISSOLVING;
            cost += countBlocks(12) * COST_SPIKE;
            cost += countBlocks(13) * COST_INVISIBLE;
            cost += SIZE_COSTS[getSizeNumber(LEVEL_WIDTH)];
            return cost;
        }
        private bool checkSubmissionReady()
        {
            if (calculateCost() > getGame().activePlayer.getMoney())
            {
                triggerErrorMessage("You have not enough money to submit this stage.");
                return false;
            }
            if (!testSuccessful)
            {
                triggerErrorMessage("You have to test your stage first!");
                return false;
            }
            if (MenuButtons.getContent("Enter Name").Length == 0)
            {
                triggerErrorMessage("You must enter a name!");
                return false;
            }
            List<String> worldlist = WebLoader.loadAllMapsNameOnly();
            foreach (String world in worldlist)
            {
                if (MenuButtons.getContent("Enter Name") == world)
                {
                    triggerErrorMessage("A stage with that name already exists!");
                    return false;
                }
            }

            if (!checkForStartAndGoal())
            {
                return false;
            }
            return true;
        }
        private bool checkForStartAndGoal()
        {
            bool goal = false;
            bool start = false;
            for (int i = 0; i < LEVEL_WIDTH; i++)
            {
                for (int j = 0; j < LEVEL_HEIGHT; j++)
                {
                    if (blocks[i, j] == 1) start = true;
                    if (blocks[i, j] == 2) goal = true;
                    if (start && goal) return true;
                }
            }
            triggerErrorMessage("You need to set start & goal first!");
            return false;
        }
        private void scroll(GameTime tpf)
        {
            MouseState state = Mouse.GetState();
            int time = tpf.ElapsedGameTime.Milliseconds;
            bool scrollingX = false;
            bool scrollingY = false;
            if (!scrolling)
            {
                if (state.X < 10 && offsetX > -WINDOW_WIDTH / 2) { if (scrollspeedX > -1)scrollspeedX -= (double)time / 500; scrollingX = true; }
                if (state.X > WINDOW_WIDTH - 10 && offsetX < LEVEL_WIDTH * BLOCK_SIZE - WINDOW_WIDTH / 2) { if (scrollspeedX < 1)scrollspeedX += (double)time / 500; scrollingX = true; }
                if (state.Y < 10 && offsetY > -WINDOW_HEIGHT / 2) { if (scrollspeedY > -1)scrollspeedY -= (double)time / 500; scrollingY = true; }
                if (state.Y > WINDOW_HEIGHT - 10 && offsetY < LEVEL_HEIGHT * BLOCK_SIZE - WINDOW_HEIGHT / 2) { if (scrollspeedY < 1)scrollspeedY += (double)time / 500; scrollingY = true; }
            }
            if (!scrollingX && scrollspeedX != 0)
            {
                if (offsetX < -WINDOW_WIDTH / 2) { scrollspeedX = 0; offsetX = -WINDOW_WIDTH / 2; }
                if (offsetX > LEVEL_WIDTH * BLOCK_SIZE - WINDOW_WIDTH / 2) { scrollspeedX = 0; offsetX = LEVEL_WIDTH * BLOCK_SIZE - WINDOW_WIDTH / 2; }
                if (Math.Abs(scrollspeedX) > 0) scrollspeedX -= ((double)time / 300) * (scrollspeedX / Math.Abs(scrollspeedX));
                if (Math.Abs(scrollspeedX) < 0.1) scrollspeedX = 0;
            }
            if (!scrollingY && scrollspeedY != 0)
            {
                if (offsetY < -WINDOW_HEIGHT / 2) { scrollspeedY = 0; offsetY = -WINDOW_HEIGHT / 2; }
                if (offsetY > LEVEL_HEIGHT * BLOCK_SIZE - WINDOW_HEIGHT / 2) { scrollspeedY = 0; offsetY = LEVEL_HEIGHT * BLOCK_SIZE - WINDOW_HEIGHT / 2; }
                if (Math.Abs(scrollspeedY) > 0) scrollspeedY -= ((double)time / 300) * (scrollspeedY / Math.Abs(scrollspeedY));
                if (Math.Abs(scrollspeedY) < 0.1) scrollspeedY = 0;
            }
            offsetX += (int)(time * scrollspeedX);
            offsetY += (int)(time * scrollspeedY);
        }
        private void leftClick()
        {
            if (!menuActive) mousePressed = true;
            if (editMode == 3)
            {
                if (selectionFrameIntersect())
                {
                    this.movingSelection = true;

                    this.startMoveSelection = getSnapPoint();
                    this.SelectionOrigin = getPostOffsetFieldCoordinates(startSelect);
                    if (!altPressed) eraseOldBlocks();
                    this.endMoveSelection = getSnapPoint();
                    this.oldEndMoveSelection = getSnapPoint();
                }
                else
                {
                    clearVariables();
                    startSelect = getSnapPoint();
                    startSelect.X += offsetX;
                    startSelect.Y += offsetY;
                    endSelect = getSnapPoint();
                    endSelect.X += offsetX;
                    endSelect.Y += offsetY;
                    selecting = true;
                }
            }
            InterfaceClick();
            leftPressed();
        }
        private void leftReleased()
        {
            mousePressed = false;
            justEntered = false;
            dropdownMapsizeActive = false;
            dropdownSettingActive = false;
            if (blocksWerePlaced)
            {
                blocksWerePlaced = false;
            }
            if (movingSelection && checkForValidDropLocation())
            {
                placeSelectedBlocks();

            }
            if (selecting)
            {
                convertSelectionFrame();
                setSelectionFrame();
            }
        }
        private void clearVariables()
        {
            startSelect = new Vector2(0, 0);
            endSelect = new Vector2(0, 0);
            selecting = false;
            movingSelection = false;
            startMoveSelection = new Vector2(0, 0);
            endMoveSelection = new Vector2(0, 0);
            oldEndMoveSelection = new Vector2(0, 0);
            selectedBlocks = new int[0, 0];
            SelectionOrigin = new Vector2(0, 0);
        }
        private void placeSelectedBlocks()
        {
            movingSelection = false;
            endMoveSelection = getSnapPoint();
            Vector2 offset = new Vector2(endMoveSelection.X - oldEndMoveSelection.X, endMoveSelection.Y - oldEndMoveSelection.Y);
            this.startSelect.X += offset.X;
            this.startSelect.Y += offset.Y;
            this.endSelect.X += offset.X;
            this.endSelect.Y += offset.Y;
            Vector2 startPoint = getPostOffsetFieldCoordinates(startSelect);
            //if(!altPressed)eraseOldBlocks();
            for (int i = 0; i < selectedBlocks.GetLength(0); i++)
            {
                for (int j = 0; j < selectedBlocks.GetLength(1); j++)
                {
                    if (selectedBlocks[i, j] != 0)
                    {
                        placeBlock(selectedBlocks[i, j], new Vector2(startPoint.X + i, startPoint.Y + j));
                    }
                }
            }

        }
        private void eraseOldBlocks()
        {
            if (checkForValidDropLocation())
            {
                for (int i = 0; i < selectedBlocks.GetLength(0); i++)
                {
                    for (int j = 0; j < selectedBlocks.GetLength(1); j++)
                    {
                        if (blocks[(int)SelectionOrigin.X + i, (int)SelectionOrigin.Y + j] == selectedBlocks[i, j]) blocks[(int)SelectionOrigin.X + i, (int)SelectionOrigin.Y + j] = 0;
                    }
                }
            }
        }
        private void rewriteOldBlocks()
        {
            if (checkForValidDropLocation())
            {
                for (int i = 0; i < selectedBlocks.GetLength(0); i++)
                {
                    for (int j = 0; j < selectedBlocks.GetLength(1); j++)
                    {
                        placeBlock(selectedBlocks[i, j], new Vector2(SelectionOrigin.X + i, SelectionOrigin.Y + j));
                        //blocks[(int)SelectionOrigin.X + i, (int)SelectionOrigin.Y + j] = selectedBlocks[i, j];
                    }
                }
            }
        }
        private void convertSelectionFrame()
        {
            if (endSelect.X < startSelect.X && endSelect.Y < startSelect.Y)
            {
                float x = startSelect.X;
                float y = startSelect.Y;
                startSelect.X = endSelect.X; //+ BLOCK_SIZE;
                startSelect.Y = endSelect.Y; //+ BLOCK_SIZE;
                endSelect.X = x;
                endSelect.Y = y;
                //size.Y -= 1;
                //size.X -= 1;
            }

            if (endSelect.X > startSelect.X - BLOCK_SIZE && endSelect.Y < startSelect.Y)
            {
                float y = startSelect.Y;
                startSelect.Y = endSelect.Y;// + BLOCK_SIZE;
                endSelect.Y = y;
                //size.Y -= 1;
            }

            if (endSelect.X < startSelect.X && endSelect.Y > startSelect.Y - BLOCK_SIZE)
            {
                float x = startSelect.X;
                startSelect.X = endSelect.X;// +BLOCK_SIZE;
                endSelect.X = x;
                //size.X -= 1;
            }
        }
        private void setSelectionFrame()
        {
            selecting = false;
            Vector2 size = new Vector2(Math.Abs(endSelect.X - startSelect.X), Math.Abs(endSelect.Y - startSelect.Y));
            Vector2 SelectionStart = new Vector2(startSelect.X, startSelect.Y);
            size.X /= BLOCK_SIZE;
            size.Y /= BLOCK_SIZE;
            size.X += 1;
            size.Y += 1;


            Vector2 start = getPostOffsetFieldCoordinates(SelectionStart);
            if (start.X < 0) start.X = 0;
            if (start.Y < 0) start.Y = 0;
            if (start.X >= LEVEL_WIDTH) start.X = (LEVEL_WIDTH - 1);
            if (start.Y >= LEVEL_HEIGHT) start.Y = (LEVEL_HEIGHT - 1);
            if (start.X + size.X < 0) start.X += (size.X - start.X);
            if (start.Y + size.Y < 0) start.Y += (size.Y - start.Y);
            if (start.X + size.X >= LEVEL_WIDTH) start.X -= LEVEL_WIDTH - start.X + size.X;
            if (start.Y + size.Y >= LEVEL_HEIGHT) start.Y -= LEVEL_HEIGHT - start.Y + size.Y;
            selectedBlocks = new int[(int)size.X, (int)size.Y];
            SelectionOrigin = new Vector2(start.X, start.Y);
            for (int i = 0; i < (int)size.X; i++)
            {
                for (int j = 0; j < (int)size.Y; j++)
                {
                    selectedBlocks[i, j] = blocks[(int)start.X + i, (int)start.Y + j];
                }
            }
        }
        private bool checkForValidDropLocation()
        {
            Vector2 size = new Vector2(Math.Abs(endSelect.X - startSelect.X), Math.Abs(endSelect.Y - startSelect.Y));
            size.X /= BLOCK_SIZE;
            size.Y /= BLOCK_SIZE;

            Vector2 start = getPostOffsetFieldCoordinates(startSelect);
            if (start.X < 0 || start.Y < 0 || start.X >= LEVEL_WIDTH || start.Y >= LEVEL_HEIGHT) return false;
            if (start.X + size.X < 0 || start.Y + size.Y < 0 || start.X + size.X >= LEVEL_WIDTH || start.Y + size.Y >= LEVEL_HEIGHT) return false;
            return true;
        }
        private void leftPressed()
        {
            if (!InterfaceIntersect())
            {
                switch (editMode)
                {
                    case 1:
                        if(mousePressed&&!justEntered)placeBlock(currentBlockType, getFieldCoordinates(getSnapPoint()));
                        break;
                    case 2:
                        removeBlock();
                        break;
                    case 3:
                        if (selecting)
                        {
                            endSelect = getSnapPoint();
                            endSelect.X += offsetX;
                            endSelect.Y += offsetY;
                        }
                        if (movingSelection)
                        {
                            endMoveSelection = getSnapPoint();
                            Vector2 offset = new Vector2(endMoveSelection.X - oldEndMoveSelection.X, endMoveSelection.Y - oldEndMoveSelection.Y);
                            this.startSelect.X += offset.X;
                            this.startSelect.Y += offset.Y;
                            this.endSelect.X += offset.X;
                            this.endSelect.Y += offset.Y;
                            oldEndMoveSelection = endMoveSelection;
                        }
                        break;
                }
            }
        }
        private bool InterfaceIntersect()
        {
            MouseState state = Mouse.GetState();
            if (state.Y > WINDOW_HEIGHT - Interface_a.Height+2) return true;
            if (state.Y > WINDOW_HEIGHT - Interface_a.Height - Interface_b.Height - 20 && state.Y < WINDOW_HEIGHT - Interface_a.Height - 20 && state.X < Interface_b.Width) return true;
            return false;
        }
        private void InterfaceClick()
        {
            MouseState state = Mouse.GetState();
            Vector2 mode;
            for (int i = 0; i < 3; i++)
            {
                mode = new Vector2(3, WINDOW_HEIGHT - Interface_b.Height - Interface_a.Height -8+drawTool.Height*i);
                if (state.X > mode.X && state.X < mode.X + drawTool.Width && state.Y > mode.Y && state.Y < mode.Y + drawTool.Height)
                {
                    clearVariables();
                    switch (i)
                    {
                        case 0:
                            editMode = 1;
                            break;
                        case 1:
                            editMode = 3;
                            break;
                        case 2:
                            editMode = 2;
                            break;
                    }
                }
            }
            mode = new Vector2(0, WINDOW_HEIGHT - menuButton.Height);
            if (state.X > mode.X && state.X < mode.X + menuButton.Width && state.Y > mode.Y && state.Y < mode.Y + menuButton.Height)
            {
                menuActive = true;
            }
            for (int i = 0; i < BUTTONSET_LENGTH[buttonset]; i++)
            {
                if (state.X > 80 + 70 * i && state.X < 80 + 70 * i + ButtonBack.Width && state.Y > WINDOW_HEIGHT - 63 && state.Y < WINDOW_HEIGHT - 63 + ButtonBack.Height)
                {
                    if (buttonset == 0) ;
                    else if (buttonset == 1)
                    {
                        setCurrentBlockType(i + 1);
                        clearVariables();
                        editMode = 1;
                    }
                    else
                    {
                        setCurrentBlockType(i + 10*(buttonset-1));
                        clearVariables();
                        editMode = 1;
                    }
                }
            }
            for (int i = 0; i < 2; i++)
            {
                if (state.X > 75+200*i && state.X < 255+200*i && state.Y > WINDOW_HEIGHT - Interface_a.Height && state.Y <  WINDOW_HEIGHT - Interface_a.Height + 20) buttonset = i+1;
            }
            /*
            if (buttonset > 0 && state.X > WINDOW_WIDTH - ButtonBack.Width-10 && state.X < WINDOW_WIDTH-10 && state.Y > WINDOW_HEIGHT - 63 && state.Y < WINDOW_HEIGHT - 63 + ButtonBack.Height)
            {
                buttonset = 0;
            }
             * */
        }
        private void setCurrentBlockType(int type)
        {
            int level = getGame().activePlayer.getCurrentLevel();
            switch (type)
            {
                case 11:
                    if (level < 2) return;
                    break;
                case 12:
                    if (level < 3) return;
                    break;
                case 13:
                    if (level < 4) return;
                    break;
            }

            currentBlockType = type;
        }
        private void placeBlock(int type, Vector2 p)
        {
            if (validPoint(p) && blocks[(int)p.X, (int)p.Y] == 0 && !checkSpecialBlockInterference(p))
            {
                if (type == 1 || type == 2)
                {
                    if (isPlaced(type))
                    {
                        triggerErrorMessage("You can only place one block of this kind.");
                    }
                    else if (freeSpaceAbove(p))
                    {
                        testSuccessful = false;
                        if (!blocksWerePlaced)
                        {
                            saveUndo();
                            blocksWerePlaced = true;
                        }
                        blocks[(int)p.X, (int)p.Y] = type;
                    }
                }
                else
                {
                    testSuccessful = false;
                    if (!blocksWerePlaced)
                    {
                        saveUndo();
                        blocksWerePlaced = true;
                    }
                    blocks[(int)p.X, (int)p.Y] = type;
                }
            }
        }
        private bool checkSpecialBlockInterference(Vector2 p)
        {
            if (p.Y + 1 >= LEVEL_HEIGHT) return false;
            if (blocks[(int)p.X, (int)p.Y + 1] == 1 || blocks[(int)p.X, (int)p.Y + 1] == 2)
            {
                return true;
            }
            return false;
        }
        private bool freeSpaceAbove(Vector2 p)
        {
            if (p.Y - 1 < 0) return false;
            if(blocks[(int)p.X, (int)p.Y - 1] == 0) return true;
            return false;
        }
        private bool noStandardBlockAbove(Vector2 p)
        {
            if (p.Y - 1 < 0) return false;
            if (blocks[(int)p.X, (int)p.Y - 1] != 10) return true;
            return false;
        }
        private bool aboveStandardBlock(Vector2 p)
        {
            if (p.Y + 1 >= LEVEL_HEIGHT) return false;
            if (blocks[(int)p.X, (int)p.Y + 1] == 10) return true;
            return false;
        }
        private bool nextToStandardBlock(Vector2 p)
        {
            if (p.Y + 1 < LEVEL_HEIGHT && blocks[(int)p.X, (int)p.Y + 1] == 10) return true;
            if (p.Y - 1 >= 0 && blocks[(int)p.X, (int)p.Y - 1] == 10) return true;
            if (p.X + 1 < LEVEL_WIDTH && blocks[(int)p.X + 1, (int)p.Y] == 10) return true;
            if (p.X - 1 >= 0 && blocks[(int)p.X - 1, (int)p.Y] == 10) return true;
            return false;

        }
        private bool isPlaced(int blocktype)
        {
            for (int i = 0; i < LEVEL_WIDTH; i++)
            {
                for (int j = 0; j < LEVEL_HEIGHT; j++)
                {
                    if (blocks[i, j] == blocktype) return true;
                }
            }
            return false;
        }
        private void triggerErrorMessage(String msg)
        {
            if (errorTimer <= 0)
            {
                getGame().pushMessage(msg, true);
                errorTimer = 1;
            }
        }
        private void removeBlock()
        {
            Vector2 p = getFieldCoordinates(getSnapPoint());
            if (validPoint(p) && blocks[(int)p.X, (int)p.Y] != 0)
            {
                blocks[(int)p.X, (int)p.Y] = 0;
                testSuccessful = false;
            }
        }
        private bool validPoint(Vector2 p)
        {
            if (p.X < 0 || p.Y < 0 || p.X >= LEVEL_WIDTH || p.Y >= LEVEL_HEIGHT) return false;

            return true;
        }
        private Vector2 getSnapPoint()
        {
            MouseState mstate = Mouse.GetState();
            int x = mstate.X - (mstate.X % BLOCK_SIZE);
            int y = mstate.Y - (mstate.Y % BLOCK_SIZE);
            int offX = offsetX % BLOCK_SIZE;
            int offY = offsetY % BLOCK_SIZE;
            if (offX < 0) offX += BLOCK_SIZE;
            if (offY < 0) offY += BLOCK_SIZE;
            if (x + BLOCK_SIZE - offX < mstate.X) x += BLOCK_SIZE;
            if (y + BLOCK_SIZE - offY < mstate.Y) y += BLOCK_SIZE;
            return new Vector2(x, y);
        }
        public override void draw(GameTime gameTime)
        {
            graphics.Clear(Color.CornflowerBlue);

            // Draw the sprite.
            drawBackground();
            drawBlocks();
            drawBorders();
            if (!menuActive) drawTools();
            drawInterface();
            if (menuActive) drawMenu(gameTime);
            if (loading || loading2) this.spriteBatch.Draw(this.loadingscreen, new Rectangle((this.getGame().GraphicsDevice.Viewport.Width / 2) - this.loadingscreen.Width / 2, (this.getGame().GraphicsDevice.Viewport.Height / 2) - this.loadingscreen.Height / 2, this.loadingscreen.Width, this.loadingscreen.Height), new Rectangle(0, 0, this.loadingscreen.Width, this.loadingscreen.Height), Color.White);

        }

        private void drawBackground()
        {
                    spriteBatch.Draw(farBG[SETTING-1], Vector2.Zero, Color.White);
                    //spriteBatch.Draw(nearBG, new Vector2(((LEVEL_WIDTH*BLOCK_SIZE)/2-offsetX),((LEVEL_HEIGHT*BLOCK_SIZE)/2-offsetY)), Color.White);
                    spriteBatch.Draw(nearBG[SETTING-1], new Vector2(-((offsetX / 2 + BG_WIDTH) % (BG_WIDTH)), (LEVEL_HEIGHT * BLOCK_SIZE - offsetY + WINDOW_HEIGHT) / 2 - BG_HEIGHT), null, Color.White, 0, Vector2.Zero, new Vector2(1f, 1f), SpriteEffects.None, 0);
                    spriteBatch.Draw(nearBG[SETTING-1], new Vector2(-((offsetX / 2 + BG_WIDTH) % (BG_WIDTH)) + (BG_WIDTH), (LEVEL_HEIGHT * BLOCK_SIZE - offsetY + WINDOW_HEIGHT) / 2 - BG_HEIGHT), null, Color.White, 0, Vector2.Zero, new Vector2(1f, 1f), SpriteEffects.None, 0);
            spriteBatch.Draw(fadeout, new Vector2(0, (LEVEL_HEIGHT * BLOCK_SIZE - offsetY + WINDOW_HEIGHT) / 2 - 90), null, Color.White, 0, Vector2.Zero, new Vector2(WINDOW_WIDTH / BLOCK_SIZE, 1f), SpriteEffects.None, 0);

        }

        private void drawBlocks()
        {
            for (int i = 0; i < LEVEL_WIDTH; i++)
            {
                for (int j = 0; j < LEVEL_HEIGHT; j++)
                {
                    Vector2 point = new Vector2(i * BLOCK_SIZE - offsetX, j * BLOCK_SIZE - offsetY);
                    drawBlock(blocks[i, j], point);
                }
            }
        }

        private void drawButtons()
        {
            int offset = 0;
            if (buttonset == 1) offset = 51 * 8;
            else
            {  
                if (SETTING == 1) offset = 51 * 4;
            }
            int level = getGame().activePlayer.getCurrentLevel();
            for (int i = 0; i < BUTTONSET_LENGTH[buttonset]; i++)
            {
                int i2 = 0;
                switch (i)
                {
                    case 0:
                        i2 = 2;
                        break;
                    case 1:
                        i2 = 3;
                        break;
                    case 2:
                        i2 = 0;
                        break;
                    case 3:
                        i2 = 1;
                        break;
                }
                if (buttonset == 1) i2 = i;
                Color color = Color.White;
                if (buttonset == 2 && level < i + 1) color = new Color(0.2f, 0.2f, 0.2f);
                
                spriteBatch.Draw(blockbuttons, new Rectangle(80 + 70 * i, WINDOW_HEIGHT - 58, 51, 51), new Rectangle(51 * i2 + offset, 0, 51, 51), color);
                //spriteBatch.Draw(Buttons[buttonset - 1, i + 1], new Vector2(80 + 70 * i, WINDOW_HEIGHT - 63), color);
            }
            if (currentBlockType <= 2) offset = 51 * 8;
            else
            {
                if (SETTING == 1) offset = 51 * 4;
            }
            if (currentBlockType < 10 && buttonset == 1) spriteBatch.Draw(blockbuttons, new Rectangle(80 + 70 * (currentBlockType - 1), WINDOW_HEIGHT - 58, 51, 51), new Rectangle(51 * getGraphicsPosition() + offset, 51, 51, 51), Color.White);
            if(currentBlockType>9&&buttonset==2)spriteBatch.Draw(blockbuttons, new Rectangle(80 + 70 * (currentBlockType-10), WINDOW_HEIGHT - 58, 51, 51), new Rectangle(51 * getGraphicsPosition() + offset, 51, 51, 51), Color.White);
        }

        private int getGraphicsPosition(){
            if (currentBlockType == 1) return 0;
            if (currentBlockType == 2) return 1;
            if (currentBlockType == 10) return 2;
            if (currentBlockType == 11) return 3;
            if (currentBlockType == 12) return 0;
            if (currentBlockType == 13) return 1;
            return 0;
        }

        private void drawInterface()
        {
            spriteBatch.Draw(Interface_a2, new Vector2(0, WINDOW_HEIGHT - Interface_a.Height), Color.Gray);
            spriteBatch.Draw(Interface_a, new Vector2(0, WINDOW_HEIGHT - Interface_a.Height), Color.Gray);
            switch (buttonset)
            {
                case 1:
                    spriteBatch.Draw(Interface_a, new Vector2(0, WINDOW_HEIGHT - Interface_a.Height), Color.White);
                    break;
                case 2:
                    spriteBatch.Draw(Interface_a2, new Vector2(0, WINDOW_HEIGHT - Interface_a.Height), Color.White);
                    break;
            }


            spriteBatch.Draw(Interface_b, new Vector2(0, WINDOW_HEIGHT - Interface_b.Height - Interface_a.Height-16), Color.White);
            drawButtons();
            /*
            int level = getGame().activePlayer.getCurrentLevel();
            for (int i = 0; i < BUTTONSET_LENGTH[buttonset]; i++)
            {
                Color color = Color.White;
                if (buttonset == 2 && level < i + 1) color = new Color(0.2f, 0.2f, 0.2f);
                if (buttonset == 0)
                {
                    spriteBatch.Draw(Buttons[i, 0], new Vector2(80+70*i, WINDOW_HEIGHT - 63), Color.White);
                }
                else spriteBatch.Draw(Buttons[buttonset-1, i+1], new Vector2(80+70*i, WINDOW_HEIGHT - 63), color);
            }
            
            if (buttonset > 0)
            {
                spriteBatch.Draw(ButtonBack, new Vector2(WINDOW_WIDTH-ButtonBack.Width-10, WINDOW_HEIGHT - 63), Color.White);
            }
             * */
            spriteBatch.Draw(drawTool, new Vector2(3, WINDOW_HEIGHT - Interface_a.Height-Interface_b.Height-8), Color.White);
            spriteBatch.Draw(moveTool, new Vector2(3, WINDOW_HEIGHT - Interface_a.Height - Interface_b.Height +drawTool.Height-8), Color.White);
            spriteBatch.Draw(eraserTool, new Vector2(3, WINDOW_HEIGHT - Interface_a.Height - Interface_b.Height  + drawTool.Height*2-8), Color.White);
            if (editMode == 1) spriteBatch.Draw(drawTool_ac, new Vector2(3, WINDOW_HEIGHT - Interface_a.Height - Interface_b.Height - 8), Color.White);
            if (editMode == 3) spriteBatch.Draw(moveTool_ac, new Vector2(3, WINDOW_HEIGHT - Interface_a.Height - Interface_b.Height + drawTool.Height - 8), Color.White);
            if (editMode == 2) spriteBatch.Draw(eraserTool_ac, new Vector2(3, WINDOW_HEIGHT - Interface_a.Height - Interface_b.Height + drawTool.Height * 2 - 8), Color.White);
            spriteBatch.Draw(menuButton, new Vector2(0, WINDOW_HEIGHT - menuButton.Height), Color.White);
            drawCashtab();
        }
        private String getSizeName(int size)
        {

                if(size==SIZE01) return SIZE01_NAME;
                if(size==SIZE02) return SIZE02_NAME;
                if(size==SIZE03) return SIZE03_NAME;
                if(size==SIZE04) return SIZE04_NAME;
                if(size == SIZE05) return SIZE05_NAME;
            return "";
        }
        private int getSizeNumber(int size)
        {

            if (size == SIZE01) return 0;
            if (size == SIZE02) return 1;
            if (size == SIZE03) return 2;
            if (size == SIZE04) return 3;
            if (size == SIZE05) return 4;
            return 0;
        }
        private void drawMenu(GameTime gameTime)
        {
            spriteBatch.Draw(preview, Vector2.Zero, null, new Color(0.2f, 0.2f, 0.2f, 0.5f), 0, Vector2.Zero, new Vector2(WINDOW_WIDTH / BLOCK_SIZE, WINDOW_HEIGHT / BLOCK_SIZE), SpriteEffects.None, 0);
            spriteBatch.Draw(SaveDraftMenu, new Vector2(WINDOW_WIDTH / 2 - menu.Width / 2, WINDOW_HEIGHT / 2 - menu.Height / 2), null, Color.White, 0, Vector2.Zero, new Vector2(1, 1), SpriteEffects.None, 0);
            MouseState ms = Mouse.GetState();
            int level = getGame().activePlayer.getCurrentLevel();
            spriteBatch.Draw(dropdown, new Rectangle((int)dropdownMapsizePos.X, (int)dropdownMapsizePos.Y, dropdown.Width, 50), new Rectangle(0, 0, dropdown.Width, 50), Color.White, 0, Vector2.Zero, SpriteEffects.None, 1);
            spriteBatch.Draw(dropdown, new Rectangle((int)dropdownSettingPos.X, (int)dropdownSettingPos.Y, dropdown.Width, 50), new Rectangle(0, 0, dropdown.Width, 50), Color.White, 0, Vector2.Zero, SpriteEffects.None, 1);
            this.spriteBatch.DrawString(this.getGame().textFont, getSizeName(LEVEL_WIDTH) + "      " + SIZE_COSTS[getSizeNumber(LEVEL_WIDTH)], new Vector2(dropdownMapsizePos.X + 15, dropdownMapsizePos.Y + 10), Color.Black, 0, Vector2.Zero, 1.2f, SpriteEffects.None, 0);
            this.spriteBatch.DrawString(this.getGame().textFont, SETTINGS[SETTING-1], new Vector2(dropdownSettingPos.X + 15, dropdownSettingPos.Y + 10), Color.Black, 0, Vector2.Zero, 1.2f, SpriteEffects.None, 0);
            if ((dropdownMapsizeActive) || (ms.X > dropdownMapsizePos.X && ms.X < dropdownMapsizePos.X + dropdown.Width && ms.Y > dropdownMapsizePos.Y && ms.Y < dropdownMapsizePos.Y + 50))
            {
                spriteBatch.Draw(dropdownSelected, new Vector2(dropdownMapsizePos.X - 1, dropdownMapsizePos.Y - 1), null, new Color(1, 1, 1, 0.2f), 0, Vector2.Zero, new Vector2(1.25f, 1), SpriteEffects.None, 0);

            }
            if ((dropdownSettingActive) || (ms.X > dropdownSettingPos.X && ms.X < dropdownSettingPos.X + dropdown.Width && ms.Y > dropdownSettingPos.Y && ms.Y < dropdownSettingPos.Y + 50))
            {
                spriteBatch.Draw(dropdownSelected, new Vector2(dropdownSettingPos.X - 1, dropdownSettingPos.Y - 1), null, new Color(1, 1, 1, 0.2f), 0, Vector2.Zero, new Vector2(1.25f, 1), SpriteEffects.None, 0);

            }
            level = level/5+1;

            if (dropdownMapsizeActive) spriteBatch.Draw(dropdown, new Rectangle((int)dropdownMapsizePos.X, (int)dropdownMapsizePos.Y + 50, dropdown.Width, dropdown.Height-50), new Rectangle(0, 50, dropdown.Width, dropdown.Height - 50), Color.White, 0, Vector2.Zero, SpriteEffects.None, 1);
            if (dropdownSettingActive) spriteBatch.Draw(dropdown, new Rectangle((int)dropdownSettingPos.X, (int)dropdownSettingPos.Y + 50, dropdown.Width, 50 * level), new Rectangle(0, 50, dropdown.Width, 50 * level), Color.White, 0, Vector2.Zero, SpriteEffects.None, 1);
            for (int i = 0; i < 5; i++)
            {
                if(dropdownMapsizeActive)this.spriteBatch.DrawString(this.getGame().textFont, getSizeName(SIZES[i])+"      "+SIZE_COSTS[i], new Vector2(dropdownMapsizePos.X + 15, dropdownMapsizePos.Y + 60+50*i), Color.Black, 0, Vector2.Zero, 1.2f, SpriteEffects.None, 0);
                if (dropdownSettingActive&&i<level) this.spriteBatch.DrawString(this.getGame().textFont, SETTINGS[i], new Vector2(dropdownSettingPos.X + 15, dropdownSettingPos.Y + 60 + 50 * i), Color.Black, 0, Vector2.Zero, 1.2f, SpriteEffects.None, 0);
            
            }
            for (int i = 0; i < 5; i++)
            {
                if (dropdownMapsizeActive &&  ms.X > dropdownMapsizePos.X && ms.X < dropdownMapsizePos.X + dropdown.Width&& ms.Y > dropdownMapsizePos.Y +50 +50 * i && ms.Y < dropdownMapsizePos.Y + 100 + 50 * i)
                {
                    spriteBatch.Draw(dropdownSelected, new Vector2(dropdownMapsizePos.X, dropdownMapsizePos.Y + 50 * (i+1)), null, new Color(1, 1, 1, 0.2f), 0, Vector2.Zero, new Vector2(1.25f, 1), SpriteEffects.None, 0);
                }
            }
            for (int i = 0; i < level; i++)
            {
                if (dropdownSettingActive &&  ms.X > dropdownSettingPos.X && ms.X < dropdownSettingPos.X + dropdown.Width&& ms.Y > dropdownSettingPos.Y +50 +50 * i && ms.Y < dropdownSettingPos.Y + 100 + 50 * i)
                {
                    spriteBatch.Draw(dropdownSelected, new Vector2(dropdownSettingPos.X , dropdownSettingPos.Y + 50 * (i+1)), null, new Color(1, 1, 1, 0.2f), 0, Vector2.Zero, new Vector2(1.25f, 1), SpriteEffects.None, 0);
                }
            }
            //spriteBatch.Draw(submission, menuPosition, Color.White);          
            if (testSuccessful)
            {
                drawTime();
            }
            MenuButtons.draw(gameTime);
            if (draftListOpen)
            {
                spriteBatch.Draw(SaveDraftMenu, menuPosition, Color.White);
                drawDraftList();
                LoadDraftButtons.draw(gameTime);
            }
            if (savingdraft)
            {
                spriteBatch.Draw(SaveDraftMenu, menuPosition, Color.White);
                SaveDraftButtons.draw(gameTime);
            }
            if (overviewOpen)
            {
                drawSubmissionOverview(gameTime);
            }
        }
        private void drawSubmissionOverview(GameTime gameTime)
        {
            spriteBatch.Draw(SubmissionOverview, menuPosition, Color.White);
            this.spriteBatch.DrawString(this.getGame().textFont, MenuButtons.getContent("Enter Name"), new Vector2(menuPosition.X + 300, menuPosition.Y + 80), Color.Black);
            this.spriteBatch.DrawString(this.getGame().textFont, SETTINGS[SETTING - 1], new Vector2(menuPosition.X + 300, menuPosition.Y + 112), Color.Black);
            String size = "";
            switch (LEVEL_WIDTH)
            {
                case SIZE01:
                    size = SIZE01_NAME;
                    break;
                case SIZE02:
                    size = SIZE02_NAME;
                    break;
                case SIZE03:
                    size = SIZE03_NAME;
                    break;
                case SIZE04:
                    size = SIZE04_NAME;
                    break;
                case SIZE05:
                    size = SIZE05_NAME;
                    break;
            }
            this.spriteBatch.DrawString(this.getGame().textFont, size, new Vector2(menuPosition.X + 300, menuPosition.Y + 150), Color.Black);
            this.spriteBatch.DrawString(this.getGame().textFont, countAllBlocks().ToString(), new Vector2(menuPosition.X + 300, menuPosition.Y + 189), Color.Black);
            this.spriteBatch.DrawString(this.getGame().textFont, calculateCost() + " / " + getGame().activePlayer.getMoney() + " $", new Vector2(menuPosition.X + 300, menuPosition.Y + 225), Color.Black);
            SubmitButton.draw(gameTime);
        }
        private void drawDraftList()
        {
            this.spriteBatch.DrawString(this.getGame().textFont, "Name", new Vector2(menuPosition.X + 20, menuPosition.Y + 5), Color.Black);
            this.spriteBatch.DrawString(this.getGame().textFont, "Creator", new Vector2(menuPosition.X + 200, menuPosition.Y + 5), Color.Black);
            this.spriteBatch.DrawString(this.getGame().textFont, "Setting", new Vector2(menuPosition.X + 340, menuPosition.Y + 5), Color.Black);
            this.spriteBatch.DrawString(this.getGame().textFont, "Size", new Vector2(menuPosition.X + 430, menuPosition.Y + 5), Color.Black);
            int offset = draftPage * MAX_DRAFT_ENTRIES;
            int max = MAX_DRAFT_ENTRIES;
            if (Drafts.Length / MAX_DRAFT_ENTRIES == draftPage) max = Drafts.Length % MAX_DRAFT_ENTRIES;
            for (int i = 0; i < max; i++)
            {
                this.spriteBatch.DrawString(this.getGame().textFont, Drafts[i + offset].name, new Vector2(menuPosition.X + 20, menuPosition.Y + 30 + 20 * i), Color.Black, 0, Vector2.Zero, 0.8f, SpriteEffects.None, 0);
                this.spriteBatch.DrawString(this.getGame().textFont, Drafts[i + offset].creator, new Vector2(menuPosition.X + 200, menuPosition.Y + 30 + 20 * i), Color.Black, 0, Vector2.Zero, 0.8f, SpriteEffects.None, 0);
                this.spriteBatch.DrawString(this.getGame().textFont, SETTINGS[Drafts[i + offset].Setting - 1], new Vector2(menuPosition.X + 340, menuPosition.Y + 30 + 20 * i), Color.Black, 0, Vector2.Zero, 0.8f, SpriteEffects.None, 0);
                String Size = "";
                switch (Drafts[i + offset].width)
                {
                    case SIZE01: Size = SIZE01_NAME; break;
                    case SIZE02: Size = SIZE02_NAME; break;
                    case SIZE03: Size = SIZE03_NAME; break;
                    case SIZE04: Size = SIZE04_NAME; break;
                    case SIZE05: Size = SIZE05_NAME; break;
                }
                this.spriteBatch.DrawString(this.getGame().textFont, Size, new Vector2(menuPosition.X + 430, menuPosition.Y + 30 + 20 * i), Color.Black, 0, Vector2.Zero, 0.8f, SpriteEffects.None, 0);
            }
            spriteBatch.Draw(preview, new Vector2(menuPosition.X + 15, menuPosition.Y + 33 + 20 * (selectedDraft % MAX_DRAFT_ENTRIES)), null, new Color(0, 0, 0, 0.1f), 0, Vector2.Zero, new Vector2(14, 0.7f), SpriteEffects.None, 0);
        }
        private void drawTime()
        {
            int time = this.besttime;
            int milisecs = time % 1000;
            time = time / 1000;
            int secs = time % 100;
            time = time / 100;
            String fTime = "Best time: ";
            if (time < 10) fTime += "0";
            fTime += time.ToString() + ":";
            if (secs < 10) fTime += "0";
            fTime += secs.ToString() + ":" + milisecs;
            this.spriteBatch.DrawString(this.getGame().textFont, fTime, new Vector2(menuPosition.X + 220, menuPosition.Y + 130), Color.Black);
        }
        private void drawSelectionFrame()
        {
            Vector2 framesize = new Vector2(endSelect.X - startSelect.X, endSelect.Y - startSelect.Y);
            framesize.X /= BLOCK_SIZE;
            framesize.Y /= BLOCK_SIZE;
            framesize.X += 1;
            framesize.Y += 1;
            Vector2 startDraw = new Vector2(startSelect.X, startSelect.Y);
            Vector2 endDraw = new Vector2(endSelect.X, endSelect.Y);
            if (endSelect.X < startSelect.X && endSelect.Y < startSelect.Y)
            {
                startDraw.X += BLOCK_SIZE;
                startDraw.Y += BLOCK_SIZE;
                framesize.X -= 2;
                framesize.Y -= 2;
            }
            if (endSelect.X > startSelect.X - BLOCK_SIZE && endSelect.Y < startSelect.Y)
            {
                startDraw.Y = endSelect.Y;
                framesize.Y = Math.Abs(framesize.Y) + 2;
            }
            if (endSelect.X < startSelect.X && endSelect.Y > startSelect.Y - BLOCK_SIZE)
            {
                startDraw.X = endSelect.X;
                framesize.X = Math.Abs(framesize.X) + 2;
            }
            startDraw.X -= (offsetX + startDraw.X % BLOCK_SIZE);
            startDraw.Y -= (offsetY + startDraw.Y % BLOCK_SIZE);
            if (checkForValidDropLocation()) spriteBatch.Draw(preview, startDraw, null, new Color(0, 0.2f, 0, 0.1f), 0, Vector2.Zero, framesize, SpriteEffects.None, 0);
            else spriteBatch.Draw(preview, startDraw, null, new Color(0.2f, 0, 0, 0.1f), 0, Vector2.Zero, framesize, SpriteEffects.None, 0);
        }
        private bool selectionFrameIntersect()
        {
            MouseState ms = Mouse.GetState();
            if (ms.X > Math.Min(startSelect.X, endSelect.X) - offsetX && ms.X < Math.Max(startSelect.X, endSelect.X) + BLOCK_SIZE - offsetX && ms.Y > Math.Min(startSelect.Y, endSelect.Y) - offsetY && ms.Y < Math.Max(startSelect.Y, endSelect.Y) + BLOCK_SIZE - offsetY)
            {
                return true;
            }
            return false;
        }

        private Vector2 getFieldCoordinates(Vector2 point)
        {
            Vector2 point2 = new Vector2((int)(point.X + offsetX) / BLOCK_SIZE, (int)(point.Y + offsetY) / BLOCK_SIZE);
            return point2;
        }

        private Vector2 getPostOffsetFieldCoordinates(Vector2 point)
        {
            Vector2 point2 = new Vector2((int)(point.X) / BLOCK_SIZE, (int)(point.Y) / BLOCK_SIZE);
            return point2;
        }

        private void drawBorders()
        {
            spriteBatch.Draw(preview, new Vector2(-offsetX - BLOCK_SIZE, -offsetY - BLOCK_SIZE), null, new Color(1, 0, 0, 0.5f), 0, Vector2.Zero, new Vector2(LEVEL_WIDTH + 1, 1), SpriteEffects.None, 0);
            spriteBatch.Draw(preview, new Vector2(-offsetX - BLOCK_SIZE, -offsetY), null, new Color(1, 0, 0, 0.5f), 0, Vector2.Zero, new Vector2(1, LEVEL_HEIGHT + 1), SpriteEffects.None, 0);
            spriteBatch.Draw(preview, new Vector2(-offsetX, -offsetY + LEVEL_HEIGHT * BLOCK_SIZE), null, new Color(1, 0, 0, 0.5f), 0, Vector2.Zero, new Vector2(LEVEL_WIDTH + 1, 1), SpriteEffects.None, 0);
            spriteBatch.Draw(preview, new Vector2(-offsetX + LEVEL_WIDTH * BLOCK_SIZE, -offsetY - BLOCK_SIZE), null, new Color(1, 0, 0, 0.5f), 0, Vector2.Zero, new Vector2(1, LEVEL_HEIGHT + 1), SpriteEffects.None, 0);
        }

        private void drawCashtab()
        {
            spriteBatch.Draw(cashtab, new Vector2(WINDOW_WIDTH - cashtab.Width, 0), Color.White);
            this.spriteBatch.DrawString(this.getGame().textFont, countAllBlocks().ToString(), new Vector2(WINDOW_WIDTH - cashtab.Width + 35, -3), Color.Black, 0, Vector2.Zero, 0.8f, SpriteEffects.None, 0);
            this.spriteBatch.Draw(blocksprites[SETTING - 1, 9], new Rectangle(WINDOW_WIDTH - cashtab.Width + 18, 1, blocksprites[SETTING - 1, 9].Width / 2, blocksprites[SETTING - 1, 9].Height / 2), new Rectangle(0, 0, blocksprites[SETTING - 1, 10].Width, blocksprites[SETTING - 1, 10].Height), Color.White);
            Color color = Color.LightGreen;
            if (calculateCost() > getGame().activePlayer.getMoney()) color = Color.Red;
            this.spriteBatch.DrawString(this.getGame().textFont, calculateCost() + " / " + getGame().activePlayer.getMoney() + "$", new Vector2(WINDOW_WIDTH  -cashtab.Width + 90, -3), color, 0, Vector2.Zero, 0.8f, SpriteEffects.None, 0); 
        }

        private void drawSelectedBlocks()
        {
            Vector2 SelectionStart = new Vector2(startSelect.X, startSelect.Y);

            for (int i = 0; i < selectedBlocks.GetLength(0); i++)
            {
                for (int j = 0; j < selectedBlocks.GetLength(1); j++)
                {
                    drawBlock(selectedBlocks[i, j], new Vector2(SelectionStart.X + BLOCK_SIZE * i - offsetX - SelectionStart.X % BLOCK_SIZE, SelectionStart.Y + BLOCK_SIZE * j - offsetY - SelectionStart.Y % BLOCK_SIZE));
                }
            }
        }
        private void drawBlock(int type, Vector2 position)
        {
            Vector2 pos = new Vector2(position.X, position.Y);
            if (type == 1 || type == 2)
            {
                pos.Y -= BLOCK_SIZE;
            }
            
            if (type == 10)
            {
                if (noStandardBlockAbove(getFieldCoordinates(position)))
                {
                    spriteBatch.Draw(blocksprites[SETTING - 1, 9], pos, Color.White);
                }
                else spriteBatch.Draw(blocksprites[SETTING - 1, 10], pos, Color.White);
            }
            else 
                if (type > 0) spriteBatch.Draw(blocksprites[SETTING-1,type], pos, Color.White);
        }
        private void drawTools()
        {
            if (editMode == 1 && !InterfaceIntersect())
            {

                Vector2 point = getSnapPoint();
                Vector2 framesize = new Vector2(1, 1);
                {
                    point.X -= offsetX % BLOCK_SIZE;
                    point.Y -= offsetY % BLOCK_SIZE;
                    if (offsetX % BLOCK_SIZE < 0) point.X -= BLOCK_SIZE;
                    if (offsetY % BLOCK_SIZE < 0) point.Y -= BLOCK_SIZE;
                }
                bool green = checkPreviewType(getFieldCoordinates(point));
                if (currentBlockType == 1 || currentBlockType == 2)
                {
                    point.Y -= BLOCK_SIZE;
                    framesize.Y = 2;
                }
                if (green)
                {
                    spriteBatch.Draw(preview, point, null, new Color(0, 1f, 0, 0.1f), 0, Vector2.Zero, framesize, SpriteEffects.None, 0);

                }
                else
                {
                    spriteBatch.Draw(preview, point, null, new Color(1f, 0, 0, 0.1f), 0, Vector2.Zero, framesize, SpriteEffects.None, 0);
                }

                spriteBatch.Draw(blocksprites[SETTING-1,currentBlockType], point, new Color(1, 1, 1, 0.5f));
            }
            if (editMode == 2 && !InterfaceIntersect())
            {
                Vector2 point = getSnapPoint();
                point.X -= offsetX % BLOCK_SIZE;
                point.Y -= offsetY % BLOCK_SIZE;
                if (offsetX % BLOCK_SIZE < 0) point.X -= BLOCK_SIZE;
                if (offsetY % BLOCK_SIZE < 0) point.Y -= BLOCK_SIZE;
                if (checkErasePreview(getFieldCoordinates(point)))
                {
                    spriteBatch.Draw(erasePreview, point, new Color(1, 1, 1, 0.5f));
                }
            }
            if (editMode == 3)
            {
                if (movingSelection) drawSelectedBlocks();
                drawSelectionFrame();
            }
        }
        
        private bool checkErasePreview(Vector2 p)
        {
            if (validPoint(p) && blocks[(int)p.X, (int)p.Y] == 0) return false;
            return true;
        }
        private bool checkPreviewType(Vector2 p)
        {
            if (validPoint(p) && blocks[(int)p.X, (int)p.Y] == 0 && !checkSpecialBlockInterference(p))
            {
                if (currentBlockType == 1 || currentBlockType == 2)
                {
                    if (!isPlaced(currentBlockType) && freeSpaceAbove(p))
                    {
                        return true;
                    }
                }
                else return true;
            }
            return false;
        }
    }
}
